# -*- coding: utf-8 -*-

# Define here the models for your spider middleware
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/spider-middleware.html
import logging
import random
import pymongo
from scrapy.exceptions import CloseSpider

from SinaWeiboSpider.settings import MONGO_URI, DB_NAME


class CookieMiddleware(object):
    """
    每次请求都随机从账号池中选择一个账号去访问
    """

    def __init__(self):
        client = pymongo.MongoClient(MONGO_URI)
        self.account_collection = client[DB_NAME]['account']

    def process_request(self, request, spider):
        all_count = self.account_collection.find({'status': 'success'}).count()
        if all_count == 0:
            spider.crawler.engine.close_spider(spider, 'ip 被封了!!!请更换ip,或者停止程序...')
            raise CloseSpider('当前账号池为空')
        random_index = random.randint(0, all_count - 1)
        random_account = self.account_collection.find({'status': 'success'})[random_index]
        request.headers.setdefault('Cookie', random_account['cookie'])
        request.meta['account'] = random_account


class RedirectMiddleware(object):
    """
    检测账号是否正常
    302 / 403,说明账号cookie失效/账号被封，状态标记为error
    418,偶尔产生,需要再次请求
    """

    def __init__(self):
        client = pymongo.MongoClient(MONGO_URI)
        self.account_collection = client[DB_NAME]['account']
        self.logger = logging

    def process_response(self, request, response, spider):
        if not self.judge(response, spider):
            spider.crawler.engine.close_spider(spider, 'ip 被封了!!!请更换ip,或者停止程序...')
            raise CloseSpider('ip 被封了!!!请更换ip,或者停止程序...')

            # self.account_collection.find_one_and_update({'_id': request.meta['account']['_id']},
            #                                             {'$set': {'status': 'error'}}, )
            # return request
        # elif http_code == 418:
        #     self.logger.error(f'{http_code} 响应信息错误')
            # spider.crawler.engine.close_spider(spider, 'ip 被封了!!!请更换ip,或者停止程序...')
            # raise CloseSpider('ip 被封了!!!请更换ip,或者停止程序...')
            # return request
        else:
            return response

    def judge(self, response, spider):
        if spider.name == 'sina_weibo_comment':
            if response.xpath('//div[@class="c" and contains(@id,"C_")]'):
                return True
            else:
                return False
        elif spider.name == 'sina_account':
            if response.xpath('body/div[@class="c"]//text()'):
                return True
            else:
                return False
        elif spider.name == 'sina_account_fans_follow':
            if response.xpath('//a[text()="关注他" or text()="关注她" or text()="取消关注"]/@href'):
                return True
            else:
                return False
        elif spider.name == 'sina_account_weibo':
            if response.xpath('//div[@class="c" and @id]') or response.xpath('string(//*[@id="M_"]/div[1])'):
                return True
            else:
                return False
        elif spider.name == 'sina_search_weibo':
            if response.xpath('//div[@class="c" and @id]'):
                return True
            else:
                return False

class IPProxyMiddleware(object):

    def fetch_proxy(self):
        # 如果需要加入代理IP，请重写这个函数
        # 这个函数返回一个代理ip，'ip:port'的格式，如'12.34.1.4:9090'
        return None

    def process_request(self, request, spider):
        proxy_data = self.fetch_proxy()
        if proxy_data:
            current_proxy = f'http://{proxy_data}'
            spider.logger.debug(f"当前代理IP:{current_proxy}")
            request.meta['proxy'] = current_proxy
